from typing import Optional, Dict, Any
from playwright.sync_api import sync_playwright, Page, Browser
from loguru import logger
from config.settings import BROWSER_HEADLESS, BROWSER_SLOWMO

class WebAutomation:
    def __init__(self):
        self.browser: Optional[Browser] = None
        self.page: Optional[Page] = None
        self.playwright = sync_playwright().start()

    def start_browser(self) -> None:
        """启动浏览器"""
        try:
            self.browser = self.playwright.chromium.launch(
                headless=BROWSER_HEADLESS,
                slow_mo=BROWSER_SLOWMO
            )
            self.page = self.browser.new_page()
            logger.info("浏览器启动成功")
        except Exception as e:
            logger.error(f"浏览器启动失败: {str(e)}")
            raise

    def navigate(self, url: str) -> None:
        """导航到指定URL"""
        try:
            self.page.goto(url)
            logger.info(f"成功导航到: {url}")
        except Exception as e:
            logger.error(f"导航失败: {str(e)}")
            raise

    def click_element(self, selector: str, timeout: int = 5000) -> None:
        """点击元素"""
        try:
            self.page.click(selector, timeout=timeout)
            logger.info(f"成功点击元素: {selector}")
        except Exception as e:
            logger.error(f"点击元素失败: {str(e)}")
            raise

    def fill_form(self, form_data: Dict[str, Any]) -> None:
        """填写表单
        Args:
            form_data: 字典格式的表单数据，key为选择器，value为填写内容
        """
        try:
            for selector, value in form_data.items():
                self.page.fill(selector, str(value))
                logger.info(f"成功填写表单字段 {selector}: {value}")
        except Exception as e:
            logger.error(f"填写表单失败: {str(e)}")
            raise

    def wait_for_selector(self, selector: str, timeout: int = 5000) -> None:
        """等待元素出现"""
        try:
            self.page.wait_for_selector(selector, timeout=timeout)
            logger.info(f"成功等待元素出现: {selector}")
        except Exception as e:
            logger.error(f"等待元素超时: {str(e)}")
            raise

    def get_element_text(self, selector: str) -> str:
        """获取元素文本内容"""
        try:
            element = self.page.query_selector(selector)
            if element:
                text = element.text_content()
                logger.info(f"成功获取元素文本: {text}")
                return text
            raise ValueError(f"未找到元素: {selector}")
        except Exception as e:
            logger.error(f"获取元素文本失败: {str(e)}")
            raise

    def close(self) -> None:
        """关闭浏览器"""
        try:
            if self.browser:
                self.browser.close()
            self.playwright.stop()
            logger.info("浏览器已关闭")
        except Exception as e:
            logger.error(f"关闭浏览器失败: {str(e)}")
            raise

    def __enter__(self):
        self.start_browser()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()